import DataManager from "./DataManager";
import Utils from "./Utils";


/**当前播放的背景音乐名字 */
let currBgmName = "";

/**背景音乐是否停止 */
let isBgmOff = false;

/**音效是否停止 */
let isEffectOff = false;

/**记录声音id的数组 */
let audioIdArr = {};

/**最大音频实例个数 */
let maxAudioInstance = cc.audioEngine.getMaxAudioInstance();

/**未停止:false */
let _audioStatus = {
    bgm: false,
    effect: false,
};

let audioPath: string = "sound/";
let isLoaded: any = {};

function _playBgm(name) {
    let url = audioPath + name;
    Utils.Instance.loadBundle(url, cc.AudioClip, (soundClicp) => {
        if (currBgmName != name) {
            return;
        }
        cc.log("播放了", name);
        cc.audioEngine.playMusic(soundClicp, true);
    });
}

function _getAudioKey(name, flag?) {
    return name + (cc.isValid(flag) ? flag : "");
}

function _playEffect(name, times = 1, callback?, flag?) {
    let url = audioPath + name;
    if (!url) {
        console.warn("音效 " + name + " 不存在");
        return;
    }
    let key = _getAudioKey(name, flag);
    if (times == -1) {
        times = cc.macro.REPEAT_FOREVER;
    }
    audioIdArr[key] = {
        times: times,
        id: -1,
    };
    let play = () => {
        Utils.Instance.loadBundle(url, cc.AudioClip, (soundClicp) => {
            if (!audioIdArr[key]) {
                console.error("audio key not found, name = %s", name);
                return;
            }
            isLoaded[url] = true;
            let id = cc.audioEngine.playEffect(soundClicp, false);
            audioIdArr[key].id = id;
            cc.audioEngine.setFinishCallback(id, fn);
        });
    }
    let fn = () => {
        if (!audioIdArr[key]) {
            return;
        }
        if (--audioIdArr[key].times > 0) {
            play();
            return;
        }
        delete audioIdArr[key];
        if (callback) callback();
    }
    play();
}

/**全局音乐文件 */
export default class AudioTools {

    protected static audioSource: cc.AudioSource;

    protected static _instance: AudioTools = null;
    public static get Instance(): AudioTools {
        if (AudioTools._instance == null) {
            AudioTools._instance = new AudioTools();
            this.audioSource = new cc.AudioSource();
            this.audioSource.volume = 0;
            isEffectOff = DataManager.Instance.getEffectIsOff();
            isBgmOff = DataManager.Instance.getBgmIsOff();
        }
        return AudioTools._instance;
    }

    //*******音效 ******/
    /** 切换音效的播放状态 并返回音效是否停止的标志状态 停止返回 true */
    switchEffect() {
        isEffectOff = !isEffectOff;
        if (isEffectOff) this.stopEffect();
        DataManager.Instance.setEffectIsOff(isEffectOff ? 0 : 1);
        return isEffectOff;
    }

    /**
     * 预加载音频(估计是音频解码会导致卡顿)
     */
    preLoadAudio(name, callback?) {
        let count = name.length;
        for (let i = 0; i < name.length; i++) {
            let url = audioPath + name[i];
            if (isLoaded[url]) {
                if (--count == 0 && callback) callback();
            } else {
                Utils.Instance.loadBundle(url, cc.AudioClip, (soundClicp) => {
                    let source = AudioTools.audioSource;
                    source.volume = 0;
                    source.clip = soundClicp;
                    source.play();
                    isLoaded[url] = true;
                    if (--count == 0 && callback) callback();
                });
            }
        }
    }

    /**
     * 播放音效 (建议播放之前预加载)  
     * @param {*} name 音效的名字
     * @param {*} times 播放次数;-1表示循环 
     * @param {*} callback 播放完成回调 
     * @param {*} flag 标记, 用于区分播放同名音效  
     */
    playEffect(name, times = 1, callback?, flag?) {
        if (!cc.isValid(name)) {
            return false;
        }
        if (isEffectOff) {
            return false;
        }
        console.log("playEffect", name, flag);
        _playEffect(name, times, callback, flag);
        return true;
    }

    /**停止播放音效 */
    stopEffect(name?, flag?) {
        // console.log("stopEffect", name, flag);
        if (!name) {
            this.stopAllEffect();
            return;
        }
        let key = _getAudioKey(name, flag);
        let data = audioIdArr[key];
        if (data) {
            cc.audioEngine.stopEffect(data.id);
            delete audioIdArr[key];
        }
    }

    stopAllEffect() {
        for (const key in audioIdArr) {
            let data = audioIdArr[key];
            if (data) {
                cc.audioEngine.stopEffect(data.id);
                delete audioIdArr[key];
            }
        }
    }

    /** 音效是否停止播放 停止返回true */
    isOffEffect() {
        return isEffectOff;
    }



    //*******背景音乐 ******/
    /** 切换背景音乐的播放模式 并返回背景是否停止的标志状态 停止返回 true*/
    switchBGM() {
        isBgmOff = !isBgmOff;
        isBgmOff ? this.pauseBGM() : this.resumeBGM();
        DataManager.Instance.setBgmIsOff(isBgmOff ? 0 : 1);
        return !isBgmOff;
    }

    /**暂停背景音乐 */
    pauseBGM() {
        isBgmOff = true;
        this.stopBGM();
    }

    /**恢复背景音乐 */
    resumeBGM() {
        isBgmOff = false;
        this.stopBGM();
        _playBgm(currBgmName);
    }

    /**背景音乐是否被静止，停止返回true */
    isStopBGM() {
        return isBgmOff;
    }

    /* 播放背景音乐，播放之前会停止当前的背景音乐  
     * name 背景音乐的名字
     */
    playBGM(name) {
        if (currBgmName == name && !isBgmOff) {
            return;
        }
        currBgmName = name;
        if (isBgmOff || !name) {
            return;
        }
        this.stopBGM();
        _playBgm(name);
    }

    /**停止播放背景音乐 */
    stopBGM() {
        cc.audioEngine.stopMusic();
    }
};

